from keep_alive import keep_alive
import discord
import os
import importlib
from discord.ext import commands
import shutil
from depend.master import save_master, load_master, is_master
from depend.restart import restart_bot

cogs = []
intents = discord.Intents.default()
intents.message_content = True
client = commands.Bot(command_prefix="#", intents=intents)
MASTER_CONFIG_FILE = "./config/master.yaml"
if not os.path.exists('./config'):
  os.makedirs('./config')


# 自动加载 cogs 文件夹中的所有模块并创建实例
def load_cogs():
  global cogs
  cogs.clear()
  for fold in os.listdir('plugin'):  # 遍历plugin目录
    if os.path.isdir(f'plugin/{fold}'):  # 如果是文件夹
      for filename in os.listdir(f'plugin/{fold}'):  # 遍历文件夹中的所有文件
        if filename.endswith('.py'):
          cog_name = filename[:-3]
          if hasattr(client, cog_name):
            module = importlib.reload(getattr(client, cog_name))
          else:
            module = importlib.import_module(f'plugin.{fold}.{cog_name}')
          if hasattr(module, 'yuanshen'):  # 确保模块里有yuanshen类
            cog_instance = getattr(module, 'yuanshen')(client)
            setattr(client, cog_name, module)
            cogs.append(cog_instance)
            print(f"载入了插件 ： {cog_name}")


# 打印用户登录和模块载入
@client.event
async def on_ready():
  print('我已经以 {0.user} 的身份登入Discord ~'.format(client))
  try:
    load_master()
  except FileNotFoundError:
    master_id = input("请输入主人id： ")
    save_master(master_id)
  load_cogs()
  # 在机器人重启后通知主人
  master_id = load_master()
  master_user = await client.fetch_user(master_id)
  await master_user.send("机器人已经重启！")


# 打印收到的所有消息//DM是私聊，和指令响应
@client.event
async def on_message(message):
  channel_name = message.channel.name if isinstance(
    message.channel, discord.TextChannel) else "DMChannel"
  user_name = message.author.name  # 获取用户的username
  print(
    f" channel: '{channel_name}' user: '{user_name}'\nReceived message: '{message.content}'.'"
  )
  if not message.author.bot:
    await client.process_commands(message)
  for cog in cogs:
    responded = await cog.my_on_message(message)
    if responded:
      print(f"响应了 {cog.__module__.split('.')[-1]}.py中的命令！")


# 插件重载
@client.command(name='reload')
async def reload(ctx):
  if is_master(ctx):
    load_cogs()
    await ctx.send("插件已经重新载入啦~.")
    print("插件已经重新载入啦~.")
  else:
    await ctx.send("对不起，只有主人才可以使用此命令.")


# 插件列表
@client.command(name='插件列表')
async def list_plugins(ctx):
  for idx, plug_dir in enumerate(os.listdir('plugin')):
    await ctx.send(f"{idx + 1}. {plug_dir.split('/')[-1]}")


# 删除插件
@client.command(name='删除插件')
async def delete_plugin(ctx):
  await ctx.send("你有以下插件哦：")
  await list_plugins(ctx)
  await ctx.send("请发送你想删除的插件序号：")

  def check(msg):
    return msg.author == ctx.author and msg.content.isdigit()

  try:
    reply = await client.wait_for('message', timeout=60.0, check=check)
    plugin_num = int(reply.content)
    plugin_dirs = os.listdir('plugin')
    to_delete = plugin_dirs[plugin_num - 1]
    await ctx.send(f"你确定要删除插件: {to_delete}? 请回复 '是' 或者 '否'.")
    reply = await client.wait_for(
      'message',
      timeout=60.0,
      check=lambda msg: msg.author == ctx.author and msg.content in ['是', '否'])
    if reply.content == '是':
      shutil.rmtree(f'plugin/{to_delete}')
      await ctx.send(f"已删除插件: {to_delete}")
    elif reply.content == '否':
      await ctx.send("已撤销删除插件的请求.")
  except TimeoutError:
    await ctx.send("超时啦！ 已经自动撤销请求~.")
  except IndexError:
    await ctx.send("没有这个插件阿？你耍我呢吧(ㄒoㄒ).")
  except Exception as e:
    await ctx.send(f"Error: {str(e)}")


# 添加插件
@client.command(name='添加插件')
async def add_plugin(ctx):
  await ctx.send("请发送插件名称~.")
  reply = await client.wait_for('message',
                                timeout=60.0,
                                check=lambda msg: msg.author == ctx.author)
  os.mkdir(f"plugin/{reply.content}")
  with open(f"plugin/{reply.content}/{reply.content}.py", 'w') as f:
    await ctx.send("请发送插件内容~.")
    reply = await client.wait_for('message',
                                  timeout=60.0,
                                  check=lambda msg: msg.author == ctx.author)
    f.write(reply.content)
  await ctx.send("新插件创好啦！")


# 重启
@client.command(name='重启')
async def restart(ctx):
  if is_master(ctx):
    await ctx.send("机器人正在重启...")
    print("机器人正在重启...")
    restart_bot()
  else:
    await ctx.send("对不起，只有主人才可以使用此命令.")


# 关机
@client.command(name='关机')
async def shutdown(ctx):
  if is_master(ctx):
    await ctx.send("机器人已关机...")
    print("机器人已关机...")
    os._exit(0)
  else:
    await ctx.send("对不起，只有主人才可以使用此命令.")


# 白嫖服务器的关键!
keep_alive()

# 原神，启动!
client.run(os.getenv('TOKEN'))
